package com.tagtraum.perf.gcviewer;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeListener;
import java.net.URL;
import java.text.DecimalFormat;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.event.SwingPropertyChangeSupport;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;

import com.tagtraum.perf.gcviewer.imp.DataReaderException;
import com.tagtraum.perf.gcviewer.imp.DataReaderFacade;
import com.tagtraum.perf.gcviewer.log.TextAreaLogHandler;
import com.tagtraum.perf.gcviewer.model.GCModel;
import com.tagtraum.perf.gcviewer.model.GCinfoibm2_6;
import com.tagtraum.perf.gcviewer.util.LocalisationHelper;


/**
 * This class holds all chart and model data panels and provides them to {@link GCDocument}
 * for layouting.
 *
 * @author <a href="mailto:hs@tagtraum.com">Hendrik Schreiber</a>
 * <p>Date: May 5, 2005<br/>
 * Time: 2:14:36 PM</p>
 */
public class ChartPanelView {

    public static final String EVENT_MINIMIZED = "minimized";
    
    private GCPreferences preferences;    
    private ModelChartImpl modelChart;
    private ModelPanel modelPanel;
    private ModelDetailsPanel modelDetailsPanel;
    private JTabbedPane modelChartAndDetailsPanel;
    private GCModel model;
    private ViewBar viewBar;
    private boolean viewBarVisible;
    private boolean minimized;
    private SwingPropertyChangeSupport propertyChangeSupport;
    private GCDocument gcDocument;
    private TextAreaLogHandler textAreaLogHandler;
    private DataReaderFacade dataReaderFacade;
    private DrawPanel drawlines;
    private JScrollPane jsp;
    private JPanel baogao;
    private JPanel modelchartJPanel;
    public JPanel getModelchartJPanel() {
		return modelchartJPanel;
	}

	public void setModelchartJPanel(JPanel modelchartJPanel) {
		this.modelchartJPanel = modelchartJPanel;
	}

	public JPanel getBaogao() {
		return baogao;
	}

	public void setBaogao(JPanel baogao) {
		this.baogao = baogao;
	}

	public ModelDetailsPanel getModelDetailsPanel() {
		return modelDetailsPanel;
	}

	public void setModelDetailsPanel(ModelDetailsPanel modelDetailsPanel) {
		this.modelDetailsPanel = modelDetailsPanel;
	}

	public JTabbedPane getModelChartAndDetailsPanel() {
		return modelChartAndDetailsPanel;
	}

	public void setModelChartAndDetailsPanel(JTabbedPane modelChartAndDetailsPanel) {
		this.modelChartAndDetailsPanel = modelChartAndDetailsPanel;
	}

	public DrawPanel getDrawlines() {
		
		 return drawlines;

	}

	public void setDrawlines(DrawPanel drawlines) {
		this.drawlines = drawlines;
	}

	public JScrollPane getJsp() {
		return jsp;
	}

	public void setJsp(JScrollPane jsp) {
		this.jsp = jsp;
	}

	public JPanel getJpanel_log() {
		return jpanel_log;
	}

	public void setJpanel_log(JPanel jpanel_log) {
		this.jpanel_log = jpanel_log;
	}

	public void setModelChart(ModelChartImpl modelChart) {
		this.modelChart = modelChart;
	}

	private JPanel jpanel_log;
    
    public ChartPanelView(GCDocument gcDocument, URL url) throws DataReaderException {
        this.gcDocument = gcDocument;
        this.preferences = gcDocument.getPreferences();
        this.modelChart = new ModelChartImpl();
        this.modelPanel = new ModelPanel();
        this.modelDetailsPanel = new ModelDetailsPanel();
        modelchartJPanel =new JPanel(new GridLayout(1, 1));
        this.modelDetailsPanel.setBackground(Color.WHITE);
        
        drawlines =null;
        baogao =new JPanel();
        jsp =new JScrollPane();
        
        jpanel_log =new JPanel();
        JScrollPane modelDetailsScrollPane = new JScrollPane(modelDetailsPanel, 
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        
        JScrollBar hScrollBar = modelDetailsScrollPane.getHorizontalScrollBar();
        hScrollBar.setUnitIncrement(10);
        JScrollBar vScrollBar = modelDetailsScrollPane.getVerticalScrollBar();
        vScrollBar.setUnitIncrement(10);
        
        this.modelChartAndDetailsPanel = new JTabbedPane(JTabbedPane.BOTTOM);//edited by wenguang.huang 2014.2.21
      

        //this.gcDocument.getReportingWindow().add(modelChart,"summary");
        //this.modelChartAndDetailsPanel.addTab(LocalisationHelper.getString("data_panel_tab_chart"), modelChart);
        modelchartJPanel.add(modelChart);
        //this.modelChartAndDetailsPanel.addTab(LocalisationHelper.getString("data_panel_tab_details"), modelDetailsScrollPane);
        //added by wenguagn.huang 2014��2��21�� ����4:42:10
       
        baogao.setBackground(Color.WHITE);
        //jsp = new JScrollPane(baogao,20,31);

        //drawlineJPanel = new JPanel();
        
        //DataDrawDemo drawlinesDataDrawDemo = new DataDrawDemo();
        //drawlinesDataDrawDemo.show(); 

      //drawlinesDataDrawDemo.gracu.myGraphics=(Graphics2D)drawlinesDataDrawDemo.jPanel1.getGraphics(); 

      //drawlinesDataDrawDemo.mp.myGraphics=(Graphics2D)drawlinesDataDrawDemo.jPanel1.getGraphics(); 

      //drawlinesDataDrawDemo.mp.myGraphics.setBackground(Color.white); 

      //drawlinesDataDrawDemo.mp.myGraphics.clearRect(0,0,650,375); 
        //jsp.setVerticalScrollBarPolicy(JScrollPane);
        
        dataReaderFacade = new DataReaderFacade();
        final GCModel model = dataReaderFacade.loadModel(url, true, gcDocument);
        //added by wenguang.huang 2014年3月1日 下午4:34:46
        model.setMarshaller(gcDocument.marshaller);
		//added end by wenguang.huang 2014年3月1日 下午4:34:46

        //deleted by wenguang.huang
        //if(model.getFormat() == GCModel.Format.IBM_VERBOSE_GC_2_6)
        {
          drawlines = new DrawPanel(model);
         
          //this.modelChartAndDetailsPanel.addTab("��ͼ", drawlines);
        }
        //JPanel linesJPanel = new JPanel();
        //linesJPanel.add(drawlines,BorderLayout.CENTER);
        
        //this.modelChartAndDetailsPanel.addTab("����", jsp);
        //this.modelChartAndDetailsPanel.addTab("�����", linesJPanel);
 
        
        //SidePanel sidePanel = new SidePanel(analyticSections, dataSections, feedbackSections);
        //this.modelChartAndDetailsPanel.addTab("�ṹ�����", new JScrollPane(sidePanel,20,31));
        
        
        jpanel_log.setLayout(new BorderLayout());
    	JScrollPane scrollPane = new JScrollPane();
    	
        //scrollPane.setHorizontalScrollBarPolicy(scrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        JTextArea jtextpane_log = new JTextArea();
        //jtextpane_log.setAutoscrolls(true);
        jpanel_log.add(jtextpane_log,BorderLayout.CENTER);
        jpanel_log.add(scrollPane);
        //jtextpane_log.setLineWrap(false);
        scrollPane.setViewportView(jtextpane_log);
        scrollPane.setViewportBorder(BorderFactory.createEtchedBorder());
        //this.modelChartAndDetailsPanel.addTab("gc.log", jpanel_log);
		//added end by wenguagn.huang 2014��2��21�� ����4:42:10


        this.viewBar = new ViewBar(this);
        this.propertyChangeSupport = new SwingPropertyChangeSupport(this);
        this.textAreaLogHandler = new TextAreaLogHandler();

        
        //added by wenguagn.huang 2014��2��26�� ����10:58:35
        jtextpane_log.setText(model.getGccontent());
        
        //drawlineJPanel.add(drawlines);
        
        GridBagLayout gbaglayout = new GridBagLayout();
        GridBagConstraints constraints = new GridBagConstraints();      
        baogao.setLayout(gbaglayout);   
        if(model.getFormat() == GCModel.Format.IBM_VERBOSE_GC_2_6)
        {
        	          	                
              final JLabel jlb = new JLabel("<HTML><U>������</U></HTML>");
              jlb.setForeground(Color.blue);
              jlb.setFont(new Font("����", 1, 16));
              jlb.setCursor(new Cursor(Cursor.HAND_CURSOR)); 
              constraints.gridx = 0;    
              constraints.gridy = 0;
              constraints.gridwidth = 1;    
              constraints.gridheight = 1;
              //constraints.fill = GridBagConstraints.BOTH;
              constraints.weightx = 1.0;           
              gbaglayout.setConstraints(jlb, constraints);
              baogao.add(jlb);
              
              final JLabel jlb_zy = new JLabel("<HTML><U>ժҪ</U></HTML>");
              jlb_zy.setForeground(Color.blue);
              jlb_zy.setFont(new Font("����", 1, 16));
              jlb_zy.setCursor(new Cursor(Cursor.HAND_CURSOR));
              constraints.gridx = 0;    
              constraints.gridy = 1;
              
             // constraints.fill = GridBagConstraints.BOTH;
              //constraints.weightx = 1.0;
              
              gbaglayout.setConstraints(jlb_zy, constraints);
              baogao.add(jlb_zy);
                           
              final JLabel jlb_tzjy= new JLabel("������");
              jlb_tzjy.setBackground(Color.WHITE);
              jlb_tzjy.setFont(new Font("����", 1, 16));
             
              constraints.ipady = 20;
              constraints.gridwidth = 1;    
              constraints.gridheight = 1;
              constraints.fill = GridBagConstraints.BOTH;
              constraints.gridx = 1;    
              constraints.gridy = 0;
             
              gbaglayout.setConstraints(jlb_tzjy, constraints);
              baogao.add(jlb_tzjy);
              String string = "";
            double nurseryer = 100 -model.Getgcinfo().getNurseryper();
            DecimalFormat df = new DecimalFormat("#.00");
            
            if(nurseryer > 70)            	
        	string ="ÿ�λ���ǰռ�õ� nursery ����ϸߣ�����ܻᵼ�����������нϳ��� nursery ����ʱ��ͽϸߵĻ���Ƶ�ʡ��뿼������ nursery ��С���Խ��͸ñ���,nurseryֵΪ: " + df.format(nurseryer)+"��";
            double totaltenureper = 100 -model.Getgcinfo().getTotaltenureper();
            if(totaltenureper >90)
            	string = string +"\n\n"+"����ǰ�����Զѵ�ƽ���ڴ�ռ����Ϊ "+df.format(totaltenureper)+"����ռ����ƫ�ߡ������ͨ�����ӶѴ�С�����Ӧ�ó������ܡ�";
            	
          final JTextArea jta = new JTextArea();
          jta.setEditable(false);
          jta.setLineWrap(true);
          jta.setWrapStyleWord(true);
          jta.setText(string);
            
           
          jta.setFont(new Font("����", 1, 14));
       
          constraints.gridx = 1;    
          constraints.gridy = 1;
          constraints.gridwidth = 2;    
          constraints.gridheight = 1;
          constraints.fill = GridBagConstraints.BOTH;
         
          constraints.weighty = GridBagConstraints.REMAINDER;
          
          gbaglayout.setConstraints(jta, constraints);
          baogao.add(jta);
          
          
          final JLabel jlb_zybq= new JLabel("ժҪ");
          jlb_zybq.setBackground(Color.WHITE);
          jlb_zybq.setFont(new Font("����", 1, 16));
         
       
          constraints.gridwidth = 1;    
          constraints.gridheight = 1;
          constraints.fill = GridBagConstraints.BOTH;
          constraints.gridx = 1;    
          constraints.gridy = 4;
          
          
          
          gbaglayout.setConstraints(jlb_zybq, constraints);
          baogao.add(jlb_zybq);
          
          
          constraints.gridx = 1;    
          constraints.gridy = 5;
          constraints.gridwidth = GridBagConstraints.REMAINDER;    
          //constraints.gridheight = 1;
          //constraints.fill = GridBagConstraints.BOTH;
          constraints.weighty = 0.0;
          TableValues tv =  new TableValues(model.Getgcinfo());
          final JTable table= new JTable(tv);
         
          //�����и�
          table.setRowHeight(30);
          //table.setAutoResizeMode(1);
          //table.getColumn( "���" ).setMaxWidth( 300 ) ;
          //table.getColumn( "ֵ" ).setMaxWidth( 200 ) ;
          
          //�����table����JScrollPane�Ż����������
          //JScrollPane jsp = new JScrollPane(table);
          TableColumn column = table.getColumnModel().getColumn(0);//0�Ǵ��ĵ�һ��
          column.setPreferredWidth(400);//����������еĿ��
          column = table.getColumnModel().getColumn(1);//0�Ǵ��ĵ�һ��
          column.setPreferredWidth(150);//����������еĿ��
          //table.setBorder(new Border);
          gbaglayout.setConstraints(table, constraints);
          baogao.add(table);
         
          jlb.addMouseListener(new MouseAdapter(){
              public void mouseClicked(MouseEvent e){
              try
              {
            	  JScrollBar jscrollBar = jsp.getVerticalScrollBar();
            	    if (jscrollBar != null)
            	        jscrollBar.setValue(jlb_tzjy.getY());
            	    jlb.setForeground(Color.orange);
              }catch(Exception ex){
              ex.printStackTrace();
              }
              }
              
          });
          
          jlb_zy.addMouseListener(new MouseAdapter(){
              public void mouseClicked(MouseEvent e){
              try
              {
            	  JScrollBar jscrollBar = jsp.getVerticalScrollBar();
            	    if (jscrollBar != null)
            	        jscrollBar.setValue(table.getY());
            	   jlb_zy.setForeground(Color.orange);
              }catch(Exception ex){
              ex.printStackTrace();
              }
              }
              
          });
          
          //jsp.add(baogao);
          //jsp.setViewportBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
          
        }
		//added end by wenguang.huang 


        setModel(model);
        // TODO delete
        model.printDetailedInformation();
    }

    /**
     * Reloads the model displayed in this chart panel if it has changed. Using the parameter
     * the parser error dialog can be suppressed.
     * 
     * @param showParserErrors if <code>true</code> parser errors will be shown
     * @return <code>true</code>, if the file has been reloaded
     * @throws DataReaderException if something went wrong reading the file
     */
    public boolean reloadModel(boolean showParserErrors) throws DataReaderException {
        if (model.getURL() == null) return false;
        if (model.isDifferent(model.getURL())) {
            setModel(dataReaderFacade.loadModel(this.model.getURL(), showParserErrors, gcDocument));
            return true;
        }
        return false;
    }

    public void invalidate() {
        modelChart.invalidate();
        modelPanel.invalidate();
        modelDetailsPanel.invalidate();
    }

    public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
        propertyChangeSupport.addPropertyChangeListener(propertyChangeListener);
    }

    public ViewBar getViewBar() {
        return viewBar;
    }

    public JTextArea getParseLog() {
        return textAreaLogHandler.getTextArea();
    }

    public boolean isViewBarVisible() {
        return viewBarVisible;
    }

    public void setViewBarVisible(boolean viewBarVisible) {
        this.viewBarVisible = viewBarVisible;
    }

    public boolean isMinimized() {
        return minimized;
    }

    public void setMinimized(boolean minimized) {
        boolean oldValue = this.minimized;
        if (minimized != this.minimized) {
            this.minimized = minimized;
            propertyChangeSupport.firePropertyChange(EVENT_MINIMIZED, oldValue, minimized);
        }
    }

    public JTabbedPane getModelChartAndDetails() {
        return modelChartAndDetailsPanel;
    }
    
    public ModelChart getModelChart() {
        return modelChart;
    }

    public ModelPanel getModelPanel() {
        return modelPanel;
    }

    public GCModel getModel() {
        return model;
    }

    public void setModel(GCModel model) {
        this.model = model;
        this.modelPanel.setModel(model);
        this.modelChart.setModel(model, preferences);
        this.modelDetailsPanel.setModel(model);
        this.viewBar.setTitle(model.getURL().toString());
    }

    public void close() {
        gcDocument.removeChartPanelView(this);
    }

    private static class ViewBar extends JPanel {
        private JLabel title = new JLabel();
        private ViewBarButton closeButton = new ViewBarButton("images/close.png", "images/close_selected.png");
        private MinMaxButton minimizeButton = new MinMaxButton();
        private ChartPanelView chartPanelView;

        public ViewBar(ChartPanelView chartPanelView) {
            this.chartPanelView = chartPanelView;
            setLayout(new GridBagLayout());
            this.title.setOpaque(false);
            this.title.setHorizontalAlignment(SwingConstants.LEFT);
            this.title.setFont(this.title.getFont().deriveFont(this.title.getFont().getSize2D()*0.8f));
            //minimize.set
            GridBagConstraints gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.weightx = 2.0;
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
            add(this.title, gridBagConstraints);
            gridBagConstraints.weightx = 0.0;
            gridBagConstraints.weighty = 1.0;
            gridBagConstraints.gridx = 1;
            gridBagConstraints.fill = GridBagConstraints.VERTICAL;
            add(minimizeButton, gridBagConstraints);
            gridBagConstraints.gridx = 2;
            add(closeButton, gridBagConstraints);

            minimizeButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    ViewBar.this.chartPanelView.setMinimized(!ViewBar.this.chartPanelView.isMinimized());
                }
            });
            closeButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    ViewBar.this.chartPanelView.close();
                }
            });
        }

        public void setTitle(String title) {
            this.title.setText(title);
        }

        protected void paintComponent(Graphics graphics) {
            //super.paintComponent(graphics);
            // paint background
            GradientPaint gradientPaint = new GradientPaint(0, 0, getBackground().darker(), 0, getHeight()/2.0f, getBackground().brighter(), true);
            Color color = graphics.getColor();
            final Graphics2D graphics2D = (Graphics2D)graphics;
            graphics2D.setPaint(gradientPaint);
            graphics2D.fillRect(0, 0, getWidth(), getHeight());
            graphics2D.setColor(color);
        }

        private static class ViewBarButton extends JButton {
            public ViewBarButton(String image1, String image2) {
                final ImageIcon imageIcon1 = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource(image1)));
                final ImageIcon imageIcon2 = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource(image2)));
                setIcons(imageIcon1, imageIcon2);
                setMargin(new Insets(0,2,0,2));
                setRolloverEnabled(true);
                setBorderPainted(false);
                setOpaque(false);
            }

            public void setIcons(final ImageIcon imageIcon1, final ImageIcon imageIcon2) {
                setIcon(imageIcon1);
                setRolloverIcon(imageIcon2);
                setSelectedIcon(imageIcon2);
            }

        }
        private static class MinMaxButton extends JButton {
            private final ImageIcon min1 = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/minimize.png")));
            private final ImageIcon min2 = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/minimize_selected.png")));
            private final ImageIcon max1 = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/maximize.png")));
            private final ImageIcon max2 = new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/maximize_selected.png")));
            private boolean minimize = true;
            public MinMaxButton() {
                setIcons(min1, min2);
                setMargin(new Insets(0,2,0,2));
                setRolloverEnabled(true);
                setBorderPainted(false);
                setOpaque(false);
                addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent event) {
                        if (minimize) {
                            setIcons(max1, max2);
                        }
                        else {
                            setIcons(min1, min2);
                        }
                        minimize = !minimize;
                    }
                });
            }

            public void setIcons(final ImageIcon imageIcon1, final ImageIcon imageIcon2) {
                setIcon(imageIcon1);
                setRolloverIcon(imageIcon2);
                setSelectedIcon(imageIcon2);
            }

        }
    }

}

 class TableValues extends AbstractTableModel{
    private static final long serialVersionUID = -8430352919270533604L;
    public final static int NAME = 0;
    public final static int GENDER = 1;
    public final static String[] columnNames = {"���", "ֵ"};
    public Object[][] values;
    DecimalFormat df = new DecimalFormat("0.00");
    public TableValues(GCinfoibm2_6 gcinfo)
           {
        Object[][] tempvalues = {  
                {"GC��ʽ",gcinfo.getGcPolicy()},  
                {"Nursery ���� - ռ�õ����� (MB)",df.format(gcinfo.getTotalmctenurebytes()/(1024.0*1024.0))},  
                {"Nursery ���� - ����֮���ƽ��ʱ���� (����)",df.format(gcinfo.getTotalScavengeIntervalms()/gcinfo.getScavengeCount())},  
                {"Nursery ���� - ��������",gcinfo.getScavengeCount()},  
                {"Nursery ���� - ƽ�����������ͣʱ�� (����)",df.format(gcinfo.getScavengedurationms()/gcinfo.getScavengeCount())}, 
                {"Nursery ���� - ��ת������ (MB)",gcinfo.getTotalmcnurserybytes()},
                {"ȫ�ֻ��� - ռ�õ����� (MB)",df.format(gcinfo.getTotalglobalbytes()/(1024.0*1024.0))},
                {"ȫ�ֻ��� - ����֮���ƽ��ʱ���� (����)",df.format(gcinfo.getTotalGlobalIntervalms()/gcinfo.getGlobalCount())},
                {"ȫ�ֻ��� - ��������",gcinfo.getGlobalCount()},
                {"ȫ�ֻ��� - ƽ�����������ͣʱ�� (����)",df.format(gcinfo.getGlobaldurationms()/gcinfo.getGlobalCount())},
                {"����ʧ�ܴ����Ļ�������",gcinfo.getAFCount()},
                {"���������ͣ����ʱ��ı��� (%)",df.format(gcinfo.getPausetimescale())},
                {"��������� (MB/����)",df.format(gcinfo.getScavengedurationms()/gcinfo.getScavengeCount())},
                {"�������ռ���",gcinfo.getConcurrencyCount()},
                {"ǿ�ƻ��ռ���",gcinfo.getForceCount()},
                {"����ڴ����� (�ֽ�)",gcinfo.getMaxBytesRequested()},
                {"����ͣʱ����� (%)",df.format(gcinfo.getRuntimescale())},
           
           };
        values =tempvalues;
           }
    public int getColumnCount() {
              return values[0].length;
    }
    public int getRowCount() {
              return values.length;
    }
    public Object getValueAt(int rowIndex, int columnIndex) {
              return values[rowIndex][columnIndex];
    }
    /**
     * ��������
     */
    public String getColumnName(int column){
              return columnNames[column];
    }
}
